package com.qcl.utils.bastDao;

import org.hibernate.query.internal.NativeQueryImpl;
import org.hibernate.transform.Transformers;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Repository
public class JPABaseDAOimpl<T, ID extends Serializable> implements JPABaseDAO<T, ID> {
    @PersistenceContext
    private EntityManager entityManager;


    @Transactional
    @Override
    public boolean save(Object entity) {
        boolean flag = false;
        try {
            entityManager.persist(entity);
            flag = true;
        } catch (Exception e) {
            System.out.println("---------------保存出错---------------");
            throw e;
        }
        return flag;
    }

    /*
     * @Autowired PagingAndSortingRepository<T, String> pasr;
     *
     * @Autowired JpaSpecificationExecutor<T> jpas;
     */
    @Transactional
    @Override
    public boolean merge(Object entity) {
        boolean flag = false;
        try {
            entityManager.merge(entity);
            flag = true;
        } catch (Exception e) {
            System.out.println("---------------保存出错---------------");
            throw e;
        }
        return flag;
    }

    @Transactional
    @Override
    public T findByid(Class<T> t, Integer integer) {
        // TODO Auto-generated method stub
        return entityManager.find(t, integer);
    }

    /**
     * hql 是这样写的 from Student where sname=?1 and age>?2
     *
     * @param hql
     * @param param
     * @return
     */

    @Override
    public List<T> findByHQL(String hql, List<Object> param) {
        Query query = entityManager.createQuery(hql);
        List<Object> filedlist = new ArrayList<>();
        if (param != null) {
            for (int i = 0; i < param.size(); i++) {
                query.setParameter(i + 1, param.get(i));
            }
        }
        List<T> listRe = query.getResultList();
        return listRe;
    }

    /**
     * sql 是这样写的 select * from student where sname=?1 and age>?2
     *
     * @param hql
     * @param map
     * @return
     */

    @Override
    public List<Object> findBySQL(String sql, List<Object> param) {
        Query query = entityManager.createNativeQuery(sql);
        if (param != null && param.size() > 0) {
            for (int i = 0; i < param.size(); i++) {
                query.setParameter(i + 1, param.get(i));
            }
        }
        // query.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.TO_LIST);
        List listRe = query.getResultList();
        // entityManager.close();
        return listRe;
    }

    /**
     * sql 是这样写的 select * from student where sname=:n and age>:a
     *
     * @param sql
     * @param map
     * @return map列表分个map
     */
    @Transactional
    @Override
    public List<Map> findBySQLMAP(String sql, Map<String, Object> paramMap) {
        Query query = entityManager.createNativeQuery(sql);
        for (String paramName : paramMap.keySet()) {
            query.setParameter(paramName, paramMap.get(paramName));
        }
        // QueryImpl impl = query.unwrap(QueryImpl.class);
        query.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        List<Map> listRe = query.getResultList();
        return listRe;
    }

    @Transactional
    @Override
    public List findByMoreFiledpages(String tablename, LinkedHashMap map, int start, int pageNumer) {
        // TODO Auto-generated method stub
        return null;
    }

    @Transactional
    @Override
    public boolean delete(T entity) {
        boolean flag = false;
        try {
            entityManager.remove(entityManager.merge(entity));
            flag = true;
        } catch (Exception e) {
            System.out.println("---------------删除出错---------------");
        }
        return flag;
    }

    @Transactional
    @Override
    public boolean update(T entity) {
        boolean flag = false;
        try {
            entityManager.merge(entity);
            flag = true;
        } catch (Exception e) {
            System.out.println("---------------更新出错---------------");
        }
        return flag;
    }

    @Transactional
    @Override
    public Integer updateMoreFiled(String tablename, LinkedHashMap map) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Object findCount(String tablename, LinkedHashMap map) {
        // TODO Auto-generated method stub
        return null;
    }

    /*
     * (non-Javadoc)
     *
     * @see xzcx.common.database.JPABaseDAO#createSQLQuery(java.lang.String)
     */
    @Transactional
    @Modifying
    @Override
    public boolean createSQLQuery(String sql) {
        boolean flag = false;
        try {
            Query query = entityManager.createNativeQuery(sql);
            int count = query.executeUpdate();
            if (count > 0) {
                flag = true;
            } else {
                flag = false;
            }

        } catch (Exception e) {
            System.out.println("---------------更新出错---------------");
        }
        return flag;
    }

    /**
     * 设置查询所需的参数
     *
     * @param query
     * @param maps
     * @return
     */
    private Query getQueryWithParameters(Query query, Map<String, Object> maps) {
        if (maps.size() > 0) {
            for (String key : maps.keySet()) {
                query.setParameter(key, maps.get(key));
            }
        }
        return query;
    }

    @Override
    public List<T> findByHQLByNameParam(String hql, Map<String, Object> maps) {
        Query query =getQueryWithParameters(entityManager.createQuery(hql),maps);
        List<Object> filedlist = new ArrayList<>();
        List<T> listRe = query.getResultList();
        return listRe;
    }
}
